package com.dominator.quartz;

import com.dominator.mybatis.dao.T_timetaskPO;
import com.dominator.repository.DaoTimeTask;
import com.dominator.socket.BeanLoader;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;

import java.util.ArrayList;
import java.util.List;


/**
 * 根据上下文获取spring类
 *
 * @author
 */
@Slf4j
public class InitQuartzJob implements ApplicationContextAware {

    private static ApplicationContext appCtx;


    public static SchedulerFactoryBean schedulerFactoryBean = null;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (this.appCtx == null) {
            this.appCtx = applicationContext;
        }
    }


    public static void init() {
        schedulerFactoryBean = (SchedulerFactoryBean) appCtx.getBean(SchedulerFactoryBean.class);
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        try {
            log.info(scheduler.getSchedulerName());
        } catch (SchedulerException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        // 这里从数据库中获取任务信息数据
        DaoTimeTask daoTimeTask = (DaoTimeTask) BeanLoader.getSpringBean("daoTimeTask");

        List<ScheduleJob> jobList = new ArrayList<ScheduleJob>();

        List<T_timetaskPO> list = daoTimeTask.getTimeTaskList();
        for (T_timetaskPO tTimetaskPO : list) {
            ScheduleJob job1 = new ScheduleJob();
            job1.setJobId(tTimetaskPO.getId());
            job1.setJobGroup(tTimetaskPO.getGroup_name()); // 任务组
            job1.setJobName(tTimetaskPO.getName());// 任务名称
            job1.setJobStatus(tTimetaskPO.getJob_status()); // 任务发布状态
            job1.setIsConcurrent(tTimetaskPO.getRun_status()); // 运行状态
            job1.setCronExpression(tTimetaskPO.getCron());
            job1.setBeanClass(tTimetaskPO.getBean_name());// 一个以所给名字注册的bean的实例
            job1.setMethodName(tTimetaskPO.getMethod_name());
            job1.setJobData(tTimetaskPO.getJob_data()); // 参数
            jobList.add(job1);
        }



        for (ScheduleJob job : jobList) {
            try {
                addJob(job);
            } catch (SchedulerException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


    /**
     * 添加任务
     *
     * @param job
     * @throws SchedulerException
     */
    public static void addJob(ScheduleJob job) throws SchedulerException {
        if (job == null || !ScheduleJob.STATUS_RUNNING.equals(job.getJobStatus())) {
            return;
        }
        Scheduler scheduler = schedulerFactoryBean.getScheduler();
        log.debug(scheduler + "...........................................add");
        TriggerKey triggerKey = TriggerKey.triggerKey(job.getJobName(), job.getJobGroup());
        CronTrigger trigger = (CronTrigger) scheduler.getTrigger(triggerKey);
        // 不存在，创建一个
        if (null == trigger) {
            Class clazz = ScheduleJob.CONCURRENT_IS.equals(job.getIsConcurrent()) ? QuartzJobFactory.class : QuartzJobFactoryDisallowConcurrentExecution.class;
            JobDetail jobDetail = JobBuilder.newJob(clazz).withIdentity(job.getJobName(), job.getJobGroup()).usingJobData("data", job.getJobData()).build();
            jobDetail.getJobDataMap().put("scheduleJob", job);
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            trigger = TriggerBuilder.newTrigger().withDescription(job.getJobId().toString()).withIdentity(job.getJobName(), job.getJobGroup())
                    .withSchedule(scheduleBuilder).build();
            scheduler.scheduleJob(jobDetail, trigger);
        } else {
            // Trigger已存在，那么更新相应的定时设置
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(job.getCronExpression());
            // 按新的cronExpression表达式重新构建trigger
            trigger = trigger.getTriggerBuilder().withIdentity(triggerKey).usingJobData("data", job.getJobData()).withSchedule(scheduleBuilder).build();
            // 按新的trigger重新设置job执行
            scheduler.rescheduleJob(triggerKey, trigger);
        }
    }
}
 
